package cn.icybear.orzjisp;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.HashSet;

import cn.icybear.orzjisp.compiler.CodeCompiler;

public class ClosureTable extends Constant {

	public ClosureTable() {
		super(null);
		varibles = new HashSet<Identifier>();
	}

	public ClosureTable(DataInputStream is) throws IOException {
		this();
		codeIndex = is.readUnsignedShort();
		selfIndex = is.readUnsignedShort();
		int len = is.readUnsignedShort();
		varibleIndexes = new int[len];
		for (int i = 0; i < len; i++) {
			varibleIndexes[i] = is.readUnsignedShort();
		}
	}

	public int codeIndex;
	public int selfIndex;
	public Identifier self;
	public int[] varibleIndexes;
//	public Expression lambdaBody;//
	private HashSet<Identifier> varibles;

	public void addVar(Identifier id) {
		varibles.add(id);
	}

	public void writeTo(DataOutputStream os, CodeCompiler cc)
			throws IOException {
		os.writeShort(varibles.size()*2+6);
		os.writeShort(codeIndex);
		os.writeShort(self == null ? 0 : cc.getConstantIndex(self));
		os.writeShort(varibles.size());
		for (Identifier id : varibles) {
			os.writeShort(cc.getConstantIndex(id));
		}
	}

	@Override
	public Object getValue() {
		return this;
	}

	@Override
	public String toString() {
		return String.format("codeIndex=%d;self=%s;varibles=%s", codeIndex,
				self, varibles);
	}
	@Override
	public boolean equals(Object obj) {
		return this==obj;
	}
	@Override
	public int hashCode() {
		return System.identityHashCode(this);
	}
}
